package com.zhouhailin.reflection.utils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 演示通过反射获取类的结构信息
 *
 * @Author：zhouhailin
 * @Date： 2023/2/9
 */
public class ReflectionUtils {
    public static void main(String[] args) throws ClassNotFoundException {

        // 得到Class对象
        Class<?> personCls = Class.forName("com.zhouhailin.reflection.utils.Person");
        // 1、getName()：获取全类名
        System.out.println(personCls.getName());
        System.out.println("==============================================================");

        // 2、getSimpleName()：获取简单类名
        System.out.println(personCls.getSimpleName());
        System.out.println("==============================================================");

        // 3、getFields()：获取所有public修饰的属性，包含本类以及父类的
        Field[] fields = personCls.getFields();
        for (Field field : fields) {
            System.out.println("本类以及父类的属性 = " + field.getName());
        }
        System.out.println("==============================================================");

        // 4、getDeclaredFields()：获取本类所有的属性
        Field[] declaredFields = personCls.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println("本类中所有的属性 = " + field.getName());
        }
        System.out.println("==============================================================");

        // 5、getMethods()：获取所有public修饰的方法，包含本类以及父类的
        Method[] methods = personCls.getMethods();
        for (Method method : methods) {
            System.out.println("本类以及父类的方法 = " + method.getName());
        }
        System.out.println("==============================================================");

        // 6、getDeclaredMethods()：获取本类中所有方法
        Method[] declaredMethods = personCls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类中所有的方法 = " + declaredMethod.getName());
        }
        System.out.println("==============================================================");

        // 7、getConstructors(): 获取所有 public 修饰的构造器，包含本类
        Constructor<?>[] constructors = personCls.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("本类的构造器 = " + constructor.getName());
        }
        System.out.println("==============================================================");

        // 8、getDeclaredConstructors()：获取本类中所有构造器
        Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("本类中所有的构造器 = " + declaredConstructor);
        }
        System.out.println("==============================================================");

        // 9、 getPackage()：以 Package 形式返回 包信息
        System.out.println(personCls.getPackage());
        System.out.println("==============================================================");

        // 10、getSuperclass()：以 Class 形式返回父类信息
        Class<?> superclass = personCls.getSuperclass();
        System.out.println("父类的 class 对象 = " + superclass);
        System.out.println("==============================================================");

        // 11、getInterfaces()：以 Class[]形式返回接口信息
        Class<?>[] interfaces = personCls.getInterfaces();
        for (Class<?> aInterface : interfaces) {
            System.out.println("接口信息 = " + aInterface);
        }
        System.out.println("==============================================================");

        // 12、getAnnotations()：以 Annotation[] 形式返回注解信息
        // 有一个注解：@Deprecated
        Annotation[] annotations = personCls.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("注解的信息 = " + annotation);
        }
        System.out.println("==============================================================");
    }
}

class A {
    public String hobby;

    public void hi() {
    }

    public A() {
    }

    public A(String name) {
    }
}

interface IA {
}

interface IB {
}

@Deprecated
class Person extends A implements IA, IB {

    public String name;
    protected static int age;
    String job;
    private double sal;

    public Person() {
    }

    public Person(String name) {
    }

    /**
     * 私有的方法
     *
     * @param name
     * @param age
     */
    private Person(String name, int age) {
    }

    public void m1(String name, int age, double sal) {
    }

    protected String m2() {
        return null;
    }

    void m3() {
    }

    private void m4() {
    }

}
